﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace ReactiveLang.Expressions
{
    [TestClass]
    public class ExpressionTests: ReactiveLangTestClassBase
    {
        [TestMethod]
        public void AssignmentMustKeepLhsEqualToRhs()
        {
            var rhs = new Variable<int>();
            var lhs = new Variable<int>();

            rhs.Value = 2;
            const int initial = 1;
            lhs.Value = initial;

            var assign = Assign(lhs, rhs);
            Run(assign);
            Assert.AreEqual(rhs.Value, lhs.Value);

            Suspend();
            Assert.AreEqual(initial, lhs.Value);

            Resume();
            Assert.AreEqual(rhs.Value, lhs.Value);

            rhs.Value++;
            Assert.AreEqual(rhs.Value, lhs.Value);

            Suspend();

            Assert.AreEqual(initial, lhs.Value);
        }

        [TestMethod]
        public void ConditionalAssignment()
        {
            var condition = new Variable<bool>();
            var state = new Variable<int>() { Value = 0 };
            var value = Expression.Constant(54);

            Run(If(condition, Assign(state, value)));

            condition.Value = true;
            Assert.AreEqual(54, state.Value);

            condition.Value = false;
            Assert.AreEqual(0, state.Value);
        }

        [TestMethod]
        public void IfTest()
        {
            var source = new Variable<int>();
            var test = new Variable<bool>();

            List<int> actual = new List<int>();
            source.If(test).Distinct().Activate(actual.Add);

            source.Value = 1;
            source.Value = 2;

            test.Value = true;

            source.Value = 3;
            source.Value = 4;

            test.Value = false;

            source.Value++;
            source.Value++;

            int[] expected = { 2, 3, 4 };
            CollectionAssert.AreEqual(expected, actual);
        }
    }
}
